#include <iostream>
#include "../include/DBUtil.hpp"
#include "../include/httplib.h"

using namespace std;

// 测试数据库连接池
void testConnectionPool() {
	try {
		// 获取数据库连接池实例，并获取当前连接池的状态
		auto& pool = *ConnectionPool::getInstance();	// 解引用指针，意味着从 ConnectionPool::getInstance() 返回的指针中取出实际的 ConnectionPool 对象。
		auto status = pool.getStats();
		cout << "数据库连接池已初始化, 状态为: " << status.idle << "/" << status.total << "个连接\n";

		// 操作测试
		// 查询
		Json::Value dbname = DBUtil::query("SELECT * FROM user LIMIT 3");
		// 查询结果从控制台输出
		cout << "查询结果: \n" << dbname.toStyledString() << endl;

		// 插入数据测试
		// 注意：user_id的值11没有单引号
		int affect = DBUtil::execute("INSERT INTO user(user_id, user_name) VALUES(11, 'sc')");

		// 输出事务成功提示
		cout << "受影响行数: " << affect << endl;
	} catch (const exception& e) {
		cerr << "错误: " << e.what() << endl;
	}
}

// http测试
void startHTTPServer() {
	httplib::Server svr;
	// 静态文件目录
	svr.set_mount_point("/", "./www");

	// 用户查询接口
	svr.Get("/api/get_info", [](const auto& req, auto& res) {
		try {
			// 从请求参数中获取limit 没有参数 默认为10条
			int limit = req.has_param("limit") ? stol(req.get_param_value("limit")) : 10;

			// 执行 查询 select sql语句 限制查询条数
			Json::Value dbname = DBUtil::query("SELECT * FROM user LIMIT " + to_string(limit));

			// 响应得到的内容为 Json 中的数据 展示在前端的client
			res.set_content(dbname.toStyledString(), "application/json");
		} catch(...) {		// 此处是一个params可变数组对象
			// 各类异常
			// 捕获返回一个异常值   设置响应状态为500（服务器错误）
			res.status = 500;
			// 代表 查询失败 返回Json的错误信息的响应
			res.set_content(R"({"error":"数据库查询错误"})", "application/json");
		}	
	});

	// 检查接口
	// 遇到 "/check" 触发请求
	svr.Get("/api/check", [](const auto&, auto& res) {
		// 检查连接池状态 关注结构体中总连接与空闲连接的数量or比例关系
		auto stats = ConnectionPool::getInstance()->getStats();

		// Json 对象对应检查信息的输出
		Json::Value check;
		check["status"] = "OK";		// 正常的状态就显示 OK
		check["connections"] = stats.idle;		// 空闲连接数

		// client 响应的内容 为Json对象中的内容 检查之后的内容  展示在前端的client
		res.set_content(check.toStyledString(), "application/json");
	});

	// 根路由（可选，如果index.html已存在可不添加）
    svr.Get("/", [](const auto&, auto& res) {
        res.set_redirect("/index.html");
    });

	// 与client的交互
	// 服务器启动信息到控制台，告诉用户服务器已启动并正在监听端口
	cout << "服务器正在运行，地址：http://localhost:8080\n";

	// 启动服务器 监听8080端口
	// 监听所有的网络接口
	svr.listen("0.0.0.0", 8080);
}

// running
int main()
{
	ifstream config("dbconfig.json");		// 数据库连接池配置文件
	Json::Value cfg;
	// 文件流对应读取进Json
	config >> cfg;

	// 配置连接信息
	// 配置文件中各项参数传入  init  函数
	// 没有指定端口和最大连接数就默认3306和10
	ConnectionPool::getInstance()->init(
		// 传参
		cfg["host"].asString(),
		cfg["user"].asString(),
		cfg["password"].asString(),
		cfg["database"].asString(),
		cfg.get("port", 3306).asInt(),
		cfg.get("max_conn", 10).asInt()
	);
	// 连接测试  验证连接是否正常
	testConnectionPool();
	// HTTP 测试 接受客户端请求
	startHTTPServer();

	return 0;
}
